﻿using System;
using System.Globalization;

namespace Microsoft.Xna.Framework.Graphics
{
	/// <summary>
	/// Represents a set of six 2D textures, one for each face of a cube.
	/// </summary>
	public class TextureCube : Texture
	{
		protected internal int size;

		#region Properties
		/// <summary>
		/// Gets the width and height of this texture resource, in pixels.
		/// </summary>
		public int Size { get { return size; } }
		#endregion

		#region Constructor
		protected internal TextureCube()
		{
		}

		/// <summary>
		/// Creates a new instance of this object.
		/// </summary>
		/// <param name="graphicsDevice">The device.</param>
		/// <param name="size">The size (in pixels) of the top-level faces of the cube texture. Subsequent levels of each face will be the truncated value of half of the previous level's pixel dimension (independently). Each dimension is clamped to a minimum of 1 pixel.</param>
		/// <param name="mipMap">True to generate a full mipmap chain, otherwise, false.</param>
		/// <param name="format">Surface data format.</param>
		public TextureCube(GraphicsDevice graphicsDevice, int size, bool mipMap, SurfaceFormat format)
		{
			base.GraphicsDevice = graphicsDevice;
			this.size = size;

			ValidateCreationParameters(size, format);

			//! TODO: if possible, implement the remainder
		}
		#endregion

		#region Protected Methods
		protected internal static void ValidateCreationParameters(int size, SurfaceFormat format)
		{
			if (size <= 0)
			{
				throw new ArgumentOutOfRangeException("size", FrameworkResources.ResourcesMustBeGreaterThanZeroSize);
			}
			if (size > 0x200)
			{
				throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, FrameworkResources.ProfileTooBig, GraphicsProfile.Reach, typeof(TextureCube).Name, 0x200));
			}
			if ((format != SurfaceFormat.Color) && (format != SurfaceFormat.Bgr565) && (format != SurfaceFormat.Bgra5551) && (format != SurfaceFormat.Bgra4444) && (format != SurfaceFormat.Dxt1) && (format != SurfaceFormat.Dxt3) && (format != SurfaceFormat.Dxt5))
			{
				throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, FrameworkResources.ProfileFormatNotSupported, GraphicsProfile.Reach, typeof(TextureCube).Name, format));
			}
		}
		#endregion

		#region Public Methods
		/// <summary>
		/// Gets a copy of cube texture data specifying a cubemap face.
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="cubeMapFace">Cubemap face.</param>
		/// <param name="data">Array of data.</param>
		public void GetData<T>(CubeMapFace cubeMapFace, T[] data) where T : struct
		{
			int length;
			Rectangle? rect = null;
			if (data != null)
			{
				length = data.Length;
			}
			else
			{
				length = 0;
			}
			this.GetData<T>(cubeMapFace, 0, rect, data, 0, length);
		}

		/// <summary>
		/// Gets a copy of cube texture data, specifying a cubemap face, start index, and number of elements.
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="cubeMapFace">Cubemap face.</param>
		/// <param name="data">Array of data.</param>
		/// <param name="startIndex">Index of the first element to get.</param>
		/// <param name="elementCount">Number of elements to get.</param>
		public void GetData<T>(CubeMapFace cubeMapFace, T[] data, int startIndex, int elementCount) where T : struct
		{
			Rectangle? rect = null;
			this.GetData<T>(cubeMapFace, 0, rect, data, startIndex, elementCount);
		}

		/// <summary>
		/// Gets a copy of cube texture data, specifying a cubemap face, mimap level, source rectangle, start index, and number of elements.
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="cubeMapFace">Cube map face.</param>
		/// <param name="level">Mipmap level.</param>
		/// <param name="rect">The section of the texture where the data will be placed. null indicates the data will be copied over the entire texture.</param>
		/// <param name="data">Array of data.</param>
		/// <param name="startIndex">Index of the first element to get.</param>
		/// <param name="elementCount">Number of elements to get.</param>
		public void GetData<T>(CubeMapFace cubeMapFace, int level, Rectangle? rect, T[] data, int startIndex, int elementCount) where T : struct
		{
			if ((data == null) || (data.Length == 0))
			{
				throw new ArgumentNullException("data", FrameworkResources.NullNotAllowed);
			}

			//! TODO: if possible, implement
		}

		public void SetData<T>(CubeMapFace cubeMapFace, T[] data) where T : struct
		{
		}

		public void SetData<T>(CubeMapFace cubeMapFace, T[] data, int startIndex, int elementCount) where T : struct
		{
		}

		public void SetData<T>(CubeMapFace cubeMapFace, int level, Rectangle? rect, T[] data, int startIndex, int elementCount) where T : struct
		{
		}
		#endregion
	}
}
